#include "prologio.h"

void readln(char * result)
{
	gets (result);
}

void readint(int * result)
{
	scanf("%d",result);
}

void readreal(float * result)
{
	scanf("%f",result);
}

void readchar(char * result)
{
	scanf("%c",result);
}

void readterm(variable * value)
{
	c_type* temp = new c_type;
	if(value->get_vartype()==Real)
		readreal(&(temp->f));
	else if(value->get_vartype()==Integer)
		readint(&(temp->i));
	else if(value->get_vartype()==String)
		readln(temp->s);
	else if(value->get_vartype()==Char)
		readchar(&(temp->c));
	value->set_value(temp);
}

void nl()
{
	printf("\n");
}

bool upper_lower(c_type *& first, c_type *& second)
{			
	bool result =  false;
	if(first!=NULL&&second!=NULL)
	{
		int i = 0;
		char * str = new char[100];
		strcpy(str,QString(second->s).toUpper().toAscii().data());
		result = strcmp(str,first->s)==0;
	}
	else if(first==NULL&&second!=NULL)
	{
		int i = 0;
		first = new c_type;
		first->s = new char[strlen(second->s)];
		strcpy(first->s,QString(second->s).toUpper().toAscii().data());
		result = true;
	} 
	else if(first!=NULL&&second==NULL) 
	{
		int i = 0;
		second = new c_type;
		second->s = new char[strlen(first->s)];
		strcpy(second->s,QString(first->s).toLower().toAscii().data());
		result = true;
	}
	return result;
}

bool char_int(c_type*& str,c_type*& i)
{
	if(str!=NULL&&i!=NULL)
	{
		int k=str->c;
		return k==i->i;
	}
	else if(str!=NULL&&i==NULL)
	{
		 i = new c_type;
		 i->i=str->c;	
		 return true;
	}
	else if(str==NULL&&i!=NULL)
	{
		str = new c_type;
		str->c=(char)(i->i);
		return true;
	}
	return false;
}

bool str_char(c_type*& str,c_type*& i)
{
	if(str!=NULL&&i!=NULL)
	{
		char* str1 = new char[2];
		str1[0]=i->c;
		str1[1]='\0';	
		return strcmp(str1,str->s)==0;
	}
	else if(str!=NULL&&i==NULL)
	{
		i = new c_type;
		i->c=str->s[0];	
		return true;
	}
	else if(str==NULL&&i!=NULL)
	{
		str = new c_type;
		str->s = new char[2];
		strcpy(str->s,QString(i->c).toAscii().data());
		return true;
	}
	return false;
}

bool str_real(c_type*& str,c_type*& i)
 {
	if(str!=NULL&&i!=NULL)
	{
		float i1;
		i1=atof(str->s);
		return abs(i1-i->f)<0.001;
	}
	else if(str!=NULL&&i==NULL)
	{
		 i = new c_type;
		 i->f=QString(str->s).toFloat();	
		 return true;
	}
	else if(str==NULL&&i!=NULL)
	{
		str = new c_type;
		str->s = new char[100];
		strcpy(str->s,QString::number(i->f).toAscii().data());
		return true;
	}
	return false;
}

bool str_int(c_type* &str,c_type* &i)
{
	if(str!=NULL&&i!=NULL)
	{
		char* str1 = new char[100];
		itoa(i->i,str1,10);
		return strcmp(str1,str->s)==0;
	}
	else if(str!=NULL&&i==NULL)
	{
		 i = new c_type;
		 i->i=atoi(str->s);	
		 return true;
	}
	else if(str==NULL&&i!=NULL)
	{
		str = new c_type;
		str->s = new char[100];
		itoa(i->i,str->s,10);
		return true;
	}
	return false;
}

bool iofunc(QString func,variable* first,variable* second) 
{
	c_type* temp1,* temp2;
	temp1 = first->get_value();
	temp2 = second->get_value();
	type type1,type2;
	bool result=true;
	if(func.compare(QString("nl"))==0)
	{
		nl();
	}
	else if(func.compare(QString("str_int"))==0)
	{
		result=str_int(temp1,temp2);
		type1 = String;
		type2 = Integer;
	}
	else if(func.compare(QString("str_real"))==0)
	{
		result=str_real(temp1,temp2);
		type1 = String;
		type2 = Real;
	}
	else if(func.compare(QString("str_char"))==0)
	{
		result=str_char(temp1,temp2);
		type1 = String;
		type2 = Char;
	}
	else if(func.compare(QString("char_int"))==0)
	{
		result=char_int(temp1,temp2);
		type1 = Char;
		type2 = Integer;
	}
	else if(func.compare(QString("upper_lower"))==0)
	{
		result=upper_lower(temp1,temp2);
		type1 = String;
		type2 = String;
	}
	else if(func.compare(QString("readint"))==0)
	{
		temp1 = new c_type;
		readint(&(temp1->i));
		type1 = Integer;
	}
	else if(func.compare(QString("readreal"))==0)
	{
		temp1 = new c_type;
		type1 = Real;
		readreal(&(temp1->f));
	}
	else if(func.compare(QString("readln"))==0)
	{
		type1 = String;
		temp1 = new c_type;
		readln(temp1->s);
	}
	else if(func.compare(QString("readchar"))==0)
	{
		temp1 = new c_type;
		type1 = Char;
		readchar(&(temp1->c));
	}
	else if(func.compare(QString("readterm"))==0)
	{
		readterm(first);
	}
	else if(func.compare(QString("write"))==0)
	{
		write(first);
	}
	else
	{
		result=false;
	}	
	if(first == NULL)
	{
		first = new variable;
	}
	if(second == NULL) 
	{
		second = new variable;
	}
	first->set_vartype(type1);
	second->set_vartype(type2);
	first->set_value(temp1);
	second->set_value(temp2);
	return result;
}

void write(variable* var)
{
	if(var->get_vartype()==String)
		puts(var->get_value()->s);
	else if(var->get_vartype()==Char)
		printf("%c",var->get_value()->c);
	else if(var->get_vartype()==Integer)
		printf("%d",var->get_value()->i);
	else if(var->get_vartype()==Real)
		printf("%f",var->get_value()->f);
}